class Student():
    def __init__(self,name,age=18):
        self.name = name
        self.age = age
        self.__resetScore() #内部访问私有方法
        self.__score = 0   #内部访问私有属性

    #私有方法:重置分数
    def __resetScore(self):
        self.__score = 50

    #公开方法：获取分数
    def get__score(self):
        print(self.name +"的分数：" + str(self.__score))

    #公开方法：设置分数,增加容错处理分数不能为负数
    def set__score(self,score):
        if score < 0:
            self.__score = 0
            return
        self.__score  = score


#测试成员可见性的代码：
stu = Student("小冬")
# stu.resetScore()    #报错，不能直接访问私有方法
# print(stu.__score)  #报错，不能直接访问私有属性

stu.get__score()    #通过公开方法访问和设置分数
stu.set__score(-1)
stu.get__score()    #0
stu.set__score(66)
stu.get__score()    #66

#不能动态设置私有变量，内部的私有属性已经被Python解释器更改为_Stu__score，
#而外部代码的这个操作实际上增加了一个__score变量，使用__dict__可以打印对象的内部属性，测试效果如下：
print(stu.__dict__) #打印stu内部属性构成
stu.__score = 100   #设置__score变量
print(stu.__dict__) #打印stu内部属性构成
'''
{'name': '小冬', 'age': 18, '_Student__score': 66}
{'name': '小冬', 'age': 18, '_Student__score': 66, '__score': 100}
'''

'''
五、成员可见性
默认情况下，Class内部创建的属性和方法，外部代码是可以通过实例直接操作的；
但有时候为了保证封装性，我们不希望这些内部属性被外部直接访问。这就需要设置成员可见性。
设置方法：在属性和方法名前面添加两个下划线__；
作用：确保了外部代码不能随意修改对象内部的状态，可以在外部访问时做一些容错性判断，代码更加健壮；
外部访问：如果设置私有后，外部代码仍需要访问这些私有属性，可以在当前类中添加公开的get和set方法

注意：
1.在Python中，变量名类似__xxx__的，也就是以双下划线开头，并且以双下划线结尾的，是特殊变量。
特殊变量是可以直接访问的，不是private变量，所以，不能用__name__、__score__这样的变量名。

2.双下划线开头的实例变量并不是一定不能从外部访问。如代码中不能直接访问__score是因为Python解释器对外
把__score变量改成了_Student__score，所以，仍然可以通过_Student__score来访问__name变量,但是强烈建议你不要这么干，因为不同版本的Python解释器还可能会把__score改成不同的变量名。
3.总的来说就是，Python本身没有任何机制阻止你干坏事，一切全靠自觉

4.Python不可以动态设置私有实例属性，通过stu.__score = 100,似乎设置了新值，其实这里只是增加了一个新的属性__score
其内部的私有实例属性其实已经被修改为"_Stu__score"
'''
